<script setup>
import {onMounted, reactive } from 'vue'
import { uuid } from '@/core/utils/Common'
import axios from '@/core/utils/AxiosUpload'
import Swal from 'sweetalert2/dist/sweetalert2.js'
import 'sweetalert2/dist/sweetalert2.min.css'
import catalogApi from '@/api/system/CatalogApi'

const props = defineProps({
  maxSize: {type: Number, default: 3}, // 最大值默认3M 
  limit: {type: Number, default: 10},  // 最大值默认3M 
  callback: {type: Function,  default: undefined}
})
const emits = defineEmits(['finish'])
const state = reactive({
  visible: false,
  previewVisible: false,  // 预览开关
  loading: false,
  precent: 0,
  catalogOptions: []
})
// 表单数据 
const formState = reactive({
  mode: 'local',
  files: [],
  catalogId: ''
})
// 打开上传对话框
const onShowModal=()=>{
  formState.files = []
  state.visible = true
}
// 保存并上传
const onFinish = values => {
  console.log('Success:', values)
  let formdata = new FormData()
  formdata.append('catalogId', formState.catalogId) 
  //将每一个文件图片都加进formdata
  formState.files.forEach(item=>{
    formdata.append('files', item.file) 
  })
  // 上传
  state.loading = true
  axios.post('/api/Upload/doUploadImage', formdata, {
    onUploadProgress: progress => {
      const precent = Math.round(progress.loaded / progress.total * 100)
      console.log('上传进度：' + progress + '%')
      state.precent = precent
    }
  }).then( res => {
    if(res.code == 0) {
      state.visible = false
      if(props.callback != undefined){
        props.callback()
      } 
      Swal.fire({
        toast: true,
        showConfirmButton: false,
        timer: 3000,
        icon: 'success',
        title: '上传到服务端成功'
      })
      emits('finish')
    }else {
      // message.error('失败::'+ res.msg)
      Swal.fire(res.msg, '', 'error')
    }
  }).catch(() => {
    // message.error('上传失败[upload failed.]')
    Swal.fire('上传失败[upload failed.]!', '', 'error')
  }).finally(()=>{
    state.loading = false
  })
}

// 
const onFinishFailed = errorInfo => {
  console.log('Failed:', errorInfo)
}
// 读图片的BASE64字符串
const getBase64= (file) =>{
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })
}
// 选择文件
const onChangeSelectedFile=async e=>{
  //
  Array.from(e.target.files).forEach(async item => {
    if((item.size / (1024*1024)) > props.maxSize) {
      Swal.fire(`请选择小于${props.maxSize}MB 的图片`, '', 'warning')
      return
    }
    const base64Body = await getBase64(item)
    const fileInfo = {uid: uuid(), name: item.name , size: item.size, type:item.type ,file: item, thumb: base64Body}
    formState.files.push(fileInfo)
  })

}
// 查看图片
const onPreviewImage = (img)=>{
  state.thumb = img.thumb
  state.previewVisible = true
}
// 删除图片
const onDeleteImage = img => {
  formState.files = formState.files.filter(item=> item.uid!= img.uid)
}
// 加载时调用
onMounted(()=>{
  catalogApi.getTreeOptions('img').then(res=>{
    if(res.code == 0) {
      state.catalogOptions =[]
      state.catalogOptions.push(res.data)
    }
  })
})
</script>
<template>
  <a-button @click="onShowModal">
    <template #icon><cloud-upload-outlined /></template>上传图片
  </a-button>
  <a-modal v-model:visible="state.visible" title="选择图片" :footer="null" style="width: 600px;">
    <a-form
      :model="formState"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 16 }" 
      autocomplete="off"
      @finish="onFinish"
      @finish-failed="onFinishFailed"
    >
      <a-form-item
        label="上传方式"
        name="mode"
        :rules="[{ required: true, message: '请选择上传方式' }]">
        <a-radio-group v-model:value="formState.mode">
          <a-radio value="local">本地上传</a-radio>
          <!-- <a-radio value="remote ">远程上传</a-radio> -->
        </a-radio-group>
      </a-form-item>
      <a-form-item
        label="选择分组"
        name="catalogId"
        :rules="[{ required: true, message: '请选择分组!' }]">
        <a-tree-select 
          v-model:value="formState.catalogId"
          :tree-data="state.catalogOptions" 
          tree-node-filter-prop="label"
          show-search 
          tree-default-expand-all
          allow-clear />
      </a-form-item>
      <a-form-item
        label="上传图片"
        name="files"
        :rules="[{ required: true, message: '请上传图片!' }]">
        <a-alert message="建议上传图片最大宽度750px，不超过3MB；仅支持jpeg、png格式，可拖拽调整上传顺序" banner />
        <div class="up-image-wrapper">
          <div v-for="(img, idx) in formState.files" :key="idx" class="up-card">
            <div class="up-thumb">
              <img class="thumb-img" :src="img.thumb">
              <div class="thumb-action">
                <div class="act-item" @click="onPreviewImage(img)"><eye-outlined /></div>
                <div class="act-item" @click="onDeleteImage(img)"><delete-outlined /></div>
              </div>
            </div>
          </div>
          <div v-if="formState.files.length < limit" class="up-card gradient">
            <div class="up-text">
              <picture-outlined />
              <span class="tips">选择图片</span>
            </div>
            <input type="file" class="up-file" multiple @change="onChangeSelectedFile">
          </div>
        </div>
        <a-image
          :width="200"
          :style="{ display: 'none' }"
          :preview="{
            visible: state.previewVisible,
            onVisibleChange: (value)=>{
              state.previewVisible = value
            },
          }"
          :src="state.thumb"
        />
      </a-form-item>
      <a-form-item :wrapper-col="{ offset: 8, span: 16 }">
        <a-button type="primary" html-type="submit">保存</a-button>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<style scoped>
.up-image-wrapper{
    display: flex;
    flex-flow: row wrap;
    .up-card {
      overflow: hidden;
      position: relative;
      border: 1px dashed rgb(233, 232, 232);
      padding: 5px;
      width: 100px;height: 100px;
      margin-right:5px; border-radius: 10px;
      background-color: #fbfaf7;
      transition: box-shadow 0.3s ease; /* 添加过渡效果 */
      .up-text {
        width: 80px;
        height: 80px;
        text-align: center;
        display: flex;
        flex-direction: column;
        justify-content: center;
        font-size: 36px;
        
        .tips {
          font-size: 12px;
          --h: 1.2em;
          line-height: var(--h);
          color: #0000;
          text-shadow:  0 var(--_t,var(--h)) #fff, 0 0 var(--_c, #000);
          background:  linear-gradient(#1095c1 0 0)   bottom/100% var(--_d, 0) no-repeat;
          overflow: hidden;
          transition: 0.3s;
        }
        .tips:hover {
          --_i: 0;
        }
      }
      .up-file {
        opacity: 0;
        width: 100px;
        height: 100px;
        border: 1px solid salmon;
        background-color: transparent;
        position: relative;
        left: -10px;
        top: -90px;
        cursor: pointer;
      }
      .up-thumb {
        overflow: hidden;
        .thumb-img { 
          width: 100%; height: 100%; 
          /* object-fit: cover; 图片保持原有比例，不拉伸。*/ 
        }
        .thumb-action {
          position: absolute;
          left: 50%;
          transform: translateX(-50%);
          bottom: 10px;
          display: flex;
          align-items: center;
          
          .act-item {
            margin: 0 2px;
            background: rgba(255, 255, 255, 0.5);
            height: 35px; width: 35px;
            text-align: center; line-height: 31px;
            border: 2px solid #fff; cursor: pointer;
            transition: all 0.4s;
          }
          .act-item:nth-child(1) {transform: translateX(-200px); }
          .act-item:nth-child(2) {transform: translateX(200px); }
          .act-item:hover {background-color: #fff; border-radius: 50%; }
        }
      }
    }
    .up-card:hover {
      color: cadetblue;
      border: 1px dashed rgb(155, 154, 154);
      box-shadow: 0 0 10px rgba(0,0,0,0.5); /* 阴影效果*/
      .up-thumb{
        .thumb-action {
          .act-item {
            transform: translateX(0); }
        }
      }
    }

    .gradient{
      filter:alpha(opacity=100 finishopacity=50 style=1 startx=0,starty=0,finishx=0,finishy=150) progid:DXImageTransform.Microsoft.gradient(startcolorstr=#fff,endcolorstr=#ccc,gradientType=0);
      -ms-filter:alpha(opacity=100 finishopacity=50 style=1 startx=0,starty=0,finishx=0,finishy=150) progid:DXImageTransform.Microsoft.gradient(startcolorstr=#fff,endcolorstr=#ccc,gradientType=0);/*IE8*/    
      background:#ccc; /* 一些不支持背景渐变的浏览器 */  
      background:-moz-linear-gradient(top, #fff, #ccc);  
      background:-webkit-gradient(linear, 0 0, 0 bottom, from(#fff), to(#ccc));  
      background:-o-linear-gradient(top, #fff, #ccc); 
    }
}
</style>